/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.tenancy.core.extensions;

import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.tenancy.api.exception.NoDataSourceConfigFound;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Stoppable;

import javax.sql.DataSource;

//todo 被[io/iec/edp/caf/security/core/spring/config/CafSecurityAutoConfiguration依赖
public class MultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl implements ServiceRegistryAwareService, Stoppable {
    /**
     * @Description: 在没有提供tenantId的情况下返回默认数据源
     */
    @Override
    protected DataSource selectAnyDataSource() {
//        serviceUnitCode, exceptionCode, message, innerException, level, bizException
//        throw new NotLoggedInException("", "0001", "未登录，请先登录", null, ExceptionLevel.Error, true);
        return TenantDataSourceProvider.getTenantDataSource(TenantDataSourceProvider.MASTERDB);
    }

    /**
     * @Description: 提供了tenantId的话就根据ID来返回数据源
     */
    @Override
    protected DataSource selectDataSource(String tenantIdentifier) {
         return TenantDataSourceProvider.getTenantDataSource(tenantIdentifier);
    }

    /**
     * 根据配置，注入master dataSource
     * @param serviceRegistry
     */
    @Override
    public void injectServices(ServiceRegistryImplementor serviceRegistry) {

        final Object dataSourceConfigValue = serviceRegistry.getService( ConfigurationService.class )
                .getSettings()
                .get( AvailableSettings.DATASOURCE );

        final DataSource hikariDataSource = (DataSource) dataSourceConfigValue;

        if ( hikariDataSource == null ) {
            throw new NoDataSourceConfigFound( "","dataSourceConfig", "Please configure the main data source!", null, ExceptionLevel.Error, false );
        }

        TenantDataSourceProvider.addDataSource( TenantDataSourceProvider.MASTERDB,  hikariDataSource);
    }

    /**
     * 清空数据源列表
     */
    @Override
    public void stop() {
        TenantDataSourceProvider.stop();
    }

}
